package com.example.service.Impl;

import com.example.Constants.SystemConstants;
import com.example.domain.ResponseResult;
import com.example.domain.dto.ChangePasswordDto;
import com.example.domain.dto.ModInitUserDto;
import com.example.domain.entity.LoginUser;
import com.example.domain.entity.User;
import com.example.domain.vo.IdNameVo;
import com.example.domain.vo.UserListVo;
import com.example.enums.AppHttpCodeEnum;
import com.example.handler.exception.SystemException;
import com.example.mapper.AuthorityMapper;
import com.example.mapper.CollegeMapper;
import com.example.mapper.RoleMapper;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import com.example.utils.RedisCache;
import com.example.utils.SecurityUtils;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private CollegeMapper collegeMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private AuthorityMapper authorityMapper;
    @Resource
    private RedisCache redisCache;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Override
    public ResponseResult getUserList(Map<String,String> map) {
        //对请求参数进行转换
        Integer college = map.get("college")==null ? null : Integer.valueOf(map.get("college"));
        Integer role = map.get("role")==null ? null : Integer.valueOf(map.get("role"));
        Integer authority = map.get("authority")==null ? null : Integer.valueOf(map.get("authority"));
        String studentid = map.get("studentid");
        String name = map.get("name");
        String grade = map.get("grade");
        //查询用户信息
        List<UserListVo> userList = userMapper.getUserList(studentid, name, grade, college, role, authority);
        //查询权限
        List<IdNameVo> authorityList = authorityMapper.selectAll();
        //查询学院
        List<IdNameVo> collegeList = collegeMapper.selectAll();
        //查询职能
        List<IdNameVo> roleList = roleMapper.selectAll();
        //封装查询结果
        Map<String, Object> stringObjectMap = new HashMap<>();
        stringObjectMap.put("userList",userList);
        stringObjectMap.put("authorityList",authorityList);
        stringObjectMap.put("collegeList",collegeList);
        stringObjectMap.put("roleList",roleList);
        return ResponseResult.okResult(stringObjectMap);
    }

    @Override
    @Transactional
    public ResponseResult deleteUser(Map<String, String> map) {
        String id = map.get("id");
        User user = userMapper.selectByPrimaryKey(id);
        if (SystemConstants.ADMIN.equals(user.getAuthority()) || SecurityUtils.getUserId().equals(id.toString())){
            throw  new SystemException(AppHttpCodeEnum.DELETE_ADMIN_ERROR);
        }
        int updateNum = userMapper.deleteUser(id);
        if (updateNum!=1){
            throw  new SystemException(AppHttpCodeEnum.DELETE_ERROR);
        }
        //删除redis中的用户信息
        redisCache.deleteObject("login:" + id);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult modInitUser(Map<String, String> map) {
        //被修改的用户id
        String userId = map.get("id");
        //校验是否修改超级管理员，与当前用户身份
        String id = SecurityUtils.getUserId();//当前用户id
        LoginUser loginUser = redisCache.getCacheObject("login:" + id);//查当前用户权限
        int authorityId = userMapper.selectAuthorityIdByUserId(userId);//查询被修改用户权限
        if(SystemConstants.ADMIN.equals(authorityId) && !SystemConstants.ADMIN.equals(loginUser.getUser().getAuthority())){
            throw new SystemException(AppHttpCodeEnum.DELETE_ADMIN_ERROR);
        }
        //返回当前用户信息
        ModInitUserDto modInitUserDto = userMapper.selectModInitUserById(userId);
        //roleList
        List<IdNameVo> roleList = roleMapper.selectAll();
        //collegeList
        List<IdNameVo> collegeList = collegeMapper.selectAll();
        //authorityList
        List<IdNameVo> authorityList = authorityMapper.selectAll();
//        List<IdNameVo> idNameVoList = authorityList.stream()
//                .filter(idNameVo -> idNameVo.getId() != SystemConstants.ADMIN)
//                .collect(Collectors.toList());
        HashMap<String, Object> listMap = new HashMap<>();
        listMap.put("roleList",roleList);
        listMap.put("collegeList",collegeList);
        listMap.put("authorityList",authorityList);
        listMap.put("userInfo",modInitUserDto);
        return ResponseResult.okResult(listMap);
    }

    @Override
    public ResponseResult modUser(User user) {
        String id = SecurityUtils.getUserId();//当前用户id
        LoginUser loginUser = redisCache.getCacheObject("login:" + id);//查当前用户权限
        int authorityId = userMapper.selectAuthorityIdByUserId(user.getId());//查询被修改用户权限
        if(SystemConstants.ADMIN.equals(authorityId) && !SystemConstants.ADMIN.equals(loginUser.getUser().getAuthority())){
            throw new SystemException(AppHttpCodeEnum.DELETE_ADMIN_ERROR);
        }
        String userId = SecurityUtils.getUserId();
        String updateBy = userMapper.selectUserNameById(userId);
        //将当前时间格式转化为Timestamp类型，如果为java.util.Date将会报错，将转为sql中可识别的格式
        java.util.Date date = new java.util.Date();
        Timestamp timeStamp = new Timestamp(date.getTime());
        //对接入的参数进行初始化
        user.setUpdateby(updateBy);
        user.setUpdatetime(timeStamp);
        user.setIsdelete(0);
        //更新用户操作
        userMapper.updateUserById(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult changePassword(ChangePasswordDto changePasswordDto) {
        //获取当前用户信息
        User user = SecurityUtils.getLoginUser().getUser();
        //被修改用户id
        String changeUserId = changePasswordDto.getId();
        //从数据库中查询被修改用户的权限
        Integer changeAuthorityId = userMapper.selectAuthorityIdByUserId(changeUserId);
        //从redis中查询当前用户的权限
        Integer nowAuthorityId = user.getAuthority();
        //对密码进行加密
        String newPassword = passwordEncoder.encode(changePasswordDto.getNewPassword());
        //当前用户为超级管理员被修改用户不为超级管理员时，修改其他人密码直接重置
        if (SystemConstants.ADMIN.equals(nowAuthorityId)&&!SystemConstants.ADMIN.equals(changeAuthorityId)){
            //密码重置
            userMapper.updatePassword(changePasswordDto.getId(),newPassword);
            //删除redis中的用户信息
            redisCache.deleteObject("login:" + changeUserId);
            return ResponseResult.okResult();
        }
        //当前用户修改自己密码
        if (user.getId().equals(changeUserId)){
            //修改密码
            userMapper.updatePassword(changePasswordDto.getId(),newPassword);
            //删除redis中的用户信息
            redisCache.deleteObject("login:" + changeUserId);
            return ResponseResult.okResult();
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
    }

    @Override
    public ResponseResult addInitUser() {
        //查询权限
        List<IdNameVo> authorityList = authorityMapper.selectAll();
        //查询学院
        List<IdNameVo> collegeList = collegeMapper.selectAll();
        //查询职能
        List<IdNameVo> roleList = roleMapper.selectAll();
        Map<String, Object> stringObjectMap = new HashMap<>();
        stringObjectMap.put("authorityList",authorityList);
        stringObjectMap.put("collegeList",collegeList);
        stringObjectMap.put("roleList",roleList);
        return ResponseResult.okResult(stringObjectMap);
    }

    @Override
    @Transactional
    public ResponseResult addUser(User user) {
        String name = userMapper.selectUserNameByStudentId(user.getStudentid());
        if (StringUtils.hasText(name)){
            throw new SystemException(AppHttpCodeEnum.STUDENT_ID_ERROR);
        }
        String UUID = creatUUID();
        //封装数据
        String newPassword = passwordEncoder.encode(user.getStudentid());
        //将当前时间格式转化为Timestamp类型，如果为java.util.Date将会报错，将转为sql中可识别的格式
        java.util.Date date = new java.util.Date();
        Timestamp timeStamp = new Timestamp(date.getTime());
        User nowUser = SecurityUtils.getLoginUser().getUser();

        user.setId(UUID);
        user.setPassword(newPassword);
        user.setUpdatetime(timeStamp);
        user.setCreatetime(timeStamp);
        user.setCreateby(nowUser.getName());
        user.setUpdateby(nowUser.getName());
        user.setIsdelete(0);

        userMapper.insert(user);
        return ResponseResult.okResult();
    }

    private String creatUUID(){
        int hashCode = java.util.UUID.randomUUID().toString().hashCode();
        if (hashCode <0){
            hashCode=-hashCode;
        }
        // 0 代表前面补充0
        // 10 代表长度为10
        // d 代表参数为正数型
        String format = String.format("%010d", hashCode).substring(0,10);
        return format;
    }


}
